#pragma once

#include <matsu.h>
#include "SRGLinc.h"
#include "SRData.h"
#include "SRMacro.h"

#if _GLES1_
//gl_quads는 nehe에서 자주쓰니까 에뮬레이팅하자
#define SORA_GL_QUADS	0x0007
#endif

namespace sora
{
	class PrimitiveModel;
	class Model;

	namespace gl
	{
		void printGLString(const char *name, GLenum s);
		void checkGlError(const char* op);
	}

#if _GLES1_
	namespace gles1
	{
		class GLMachine;
		class GLStateContainer;
		class PrimitiveModelDrawer;

		class GLMachine {
		public:
			~GLMachine();
			static GLMachine &machine();

			void addVertex(float x, float y, float z);
			void setTexCoord(float s, float t);

			void glBegin(GLenum mode);
			void glEnd();
		private:
			GLMachine();

			void reset();
			void validate();

			void glesDraw();
			void soraDraw();	//opengles에는 없지만 opengl에는 있는 거 흉내내기

			bool isTexCoordEnabled() const;
			bool texCoordEnable_;

			GLenum drawMode_;
			matsu::vec2 texCoord_;
			std::vector<Vertex3> vertexVec_;
		};

		class GLStateContainer {
		public:
			GLStateContainer();
			void save();
			void restore();
		private:
			bool saved_;
			GLboolean vertexArrayEnable_;
			GLboolean colorArrayEnable_;
			GLboolean texCoordArrayEnable_;
			GLboolean normalArrayEnable_;

			GLboolean lightingEnable_;
			GLboolean tex2dEnable_;

			GLboolean cullEnable_;
		};

		//opengl raw function
		void glBegin(GLenum mode);
		void glEnd();

		void glVertex2f(GLfloat x, GLfloat y);
		void glVertex3f(GLfloat	x, GLfloat y,GLfloat z);

		void glTexCoord2f(GLfloat s, GLfloat t);

		//glut draw function
		void glutSolidCube(GLfloat size);
		void glutWireCube(GLfloat size);

		void glutSolidSphere(GLfloat radius, GLint slices, GLint stacks);
		void glutWireSphere(GLfloat radius, GLint slices, GLint stacks);

		void glutSolidCone(GLfloat base, GLfloat height, GLint slices, GLint stacks);
		void glutWireCone(GLfloat base, GLfloat height, GLint slices, GLint stacks);

		void drawModel(const sora::Model *model);

		//camera function
		void gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar);
		void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez,
					   GLfloat centerx, GLfloat centery, GLfloat centerz,
					   GLfloat upx, GLfloat upy, GLfloat upz);
	}
#endif
}
